home *** CD-ROM | disk | FTP | other *** search
- /* Magic Shadow Archiver (MSA) disk archiver client for XAD.
- * Copyright (C) 2000 Stuart Caie <kyzer@4u.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /* This XAD client reads 'Magic Shadow Archiver' disk images and writes
- * them out as '.ST' (raw Atari ST disk) files, or allows them to be
- * written to MSDOS/GEM-formatted disks.
- *
- * $VER: MSA.c 1.1 (06.08.2000)
- *
- * File format info from Damien Burke,
- * see http://www.jetman.dircon.co.uk/st/
- */
-
- #include <libraries/xadmaster.h>
- #include <proto/xadmaster.h>
-
- #include "SDI_compiler.h"
- #include "ConvertE.c"
-
- #ifndef XADMASTERFILE
- #define MSA_Client FirstClient
- #define NEXTCLIENT NULL
- const UBYTE version[] = "$VER: MSA 1.1 (06.08.2000)";
- #endif
- #define MSA_VERSION 1
- #define MSA_REVISION 1
-
- #define XADBASE REG(a6, struct xadMasterBase *xadMasterBase)
-
- /* work-doing macros */
- #define SKIP(offset) if ((err = xadHookAccess(XADAC_INPUTSEEK, \
- (ULONG)(offset), NULL, ai))) goto exit_handler
- #define READ(buffer,length) if ((err = xadHookAccess(XADAC_READ, \
- (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
- #define WRITE(buffer,length) if ((err = xadHookAccess(XADAC_WRITE, \
- (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
- #define COPY(length) if ((err = xadHookAccess(XADAC_COPY, \
- (ULONG)(length), NULL, ai))) goto exit_handler
- #define ALLOC(t,v,l) if (!((v) = (t) xadAllocVec((l),0))) ERROR(NOMEMORY)
- #define FREE(obj) xadFreeObjectA((APTR)(obj),NULL)
- #define ERROR(error) do { err = XADERR_##error; goto exit_handler; } while(0)
-
-
-
- ASM(BOOL) MSA_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *d), XADBASE) {
- return (BOOL) (d[0]==0x0E &&d[1]==0x0F && d[4]==0 && d[5]<2);
- }
-
- ASM(LONG) MSA_GetInfo(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
- struct xadDiskInfo *xdi;
- UBYTE buffer[10];
- LONG err;
-
- /* it's so simple here, I won't use the normal ALLOCOBJ/READ macros */
- xdi = (struct xadDiskInfo *) xadAllocObjectA(XADOBJ_DISKINFO, NULL);
- if (!(ai->xai_DiskInfo = xdi)) return XADERR_NOMEMORY;
- if ((err = xadHookAccess(XADAC_READ, 10, (APTR)&buffer, ai))) return err;
-
- xdi->xdi_EntryNumber = 1;
- xdi->xdi_TrackSectors = EndGetM16(&buffer[2]);
- xdi->xdi_Heads = EndGetM16(&buffer[4]) + 1;
- xdi->xdi_LowCyl = EndGetM16(&buffer[6]);
- xdi->xdi_HighCyl = EndGetM16(&buffer[8]);
- xdi->xdi_SectorSize = 512;
- xdi->xdi_Cylinders = xdi->xdi_HighCyl + 1;
- xdi->xdi_CylSectors = xdi->xdi_TrackSectors * xdi->xdi_Heads;
- xdi->xdi_TotalSectors = xdi->xdi_Cylinders * xdi->xdi_CylSectors;
- xdi->xdi_Flags = XADDIF_SEEKDATAPOS | XADDIF_GUESSCYLINDERS;
- xdi->xdi_DataPos = 10;
- return XADERR_OK;
- }
-
- ASM(LONG) MSA_UnArchive(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
- UBYTE buffer[2], *in = NULL, *out, *i, *o, *end, code;
- struct xadDiskInfo *di = ai->xai_CurDisk;
- UWORD inlen = 0, outlen = di->xdi_TrackSectors << 9;
- UWORD trklen, run, cyl, head;
- LONG err = XADERR_OK;
-
- /* allocate output buffer */
- ALLOC(UBYTE *, out, outlen);
-
- for (cyl = di->xdi_LowCyl; cyl <= ai->xai_HighCyl; cyl++) {
- for (head = 0; head < di->xdi_Heads; head++) {
- READ(&buffer, 2);
- trklen = EndGetM16(buffer);
- if (cyl >= ai->xai_LowCyl) {
- if (trklen > outlen) { ERROR(OUTPUT); }
- if (trklen == outlen) { COPY(trklen); }
- else {
- /* (re)allocate input buffer if necessary */
- if (trklen > inlen) {
- if (in) FREE(in);
- ALLOC(UBYTE *, in, (inlen = trklen));
- }
-
- /* read and un-RLE this track's data */
- READ(in, trklen);
- i = in;
- o = out;
- end = out + outlen;
- while (o < end) {
- if ((code = *i++) != 0xE5) *o++ = code;
- else {
- code = *i; run = EndGetM16(i+1); i += 3;
- if (o+run > end) ERROR(OUTPUT);
- while (run--) *o++ = code;
- }
- }
- WRITE(out, outlen);
- }
- }
- else {
- SKIP(trklen);
- }
- }
- }
-
- exit_handler:
- if (in) FREE(in);
- if (out) FREE(out);
- return err;
- }
-
- const struct xadClient MSA_Client = {
- NEXTCLIENT, XADCLIENT_VERSION, 4, MSA_VERSION, MSA_REVISION,
- 10, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO,
- 0, "MSA",
- (BOOL (*)()) MSA_RecogData,
- (LONG (*)()) MSA_GetInfo,
- (LONG (*)()) MSA_UnArchive,
- NULL
- };
-